<?php


namespace app\index\controller;

class Install extends \app\common\Controller
{
	private $error = -1;
	private $success = 1;
	private $mysql_prefix = "aimakeji_";
	public function IsInstall()
	{
		$this->chmodDir("../application/", 493);
		$database = \think\facade\Config::get("database.");
		if (empty($database["hostname"]) || empty($database["database"]) || empty($database["username"]) || empty($database["password"]) || empty($database["prefix"]) || !is_file("../system/install/install.lock")) {
			return 0;
		} else {
			return 1;
		}
	}
	private function chmodDir($path, $filemode) : bool
	{
		if (!is_dir($path)) {
			return chmod($path, $filemode);
		}
		$dh = opendir($path);
		while (($file = readdir($dh)) !== false) {
			if ($file != "." && $file != "..") {
				$fullpath = $path . "/" . $file;
				if (is_link($fullpath)) {
					return false;
				} else {
					if (!is_dir($fullpath) && !chmod($fullpath, $filemode)) {
						return false;
					} else {
						if (!$this->chmodDir($fullpath, $filemode)) {
							return false;
						}
					}
				}
			}
		}
		closedir($dh);
		if (chmod($path, $filemode)) {
			return true;
		} else {
			return false;
		}
	}
	public function Install()
	{
		if ($this->IsInstall()) {
			return json(["code" => $this->error, "msg" => "程序已安装"]);
		}
		try {
			file_put_contents("./test", time());
			file_get_contents("./test");
			unlink("./test");
		} catch (\Exception $e) {
			return json(["code" => $this->error, "msg" => "文件读写测试失败，请检查站点文件权限，" . $e->getMessage()]);
		}
		$post = \think\facade\Request::post();
		if (isset($post["mysql_hostname"]) && isset($post["mysql_database"]) && isset($post["mysql_username"]) && isset($post["mysql_password"]) && isset($post["mysql_hostport"]) && isset($post["system_product_key"]) && isset($post["admin_account"]) && isset($post["admin_password"])) {
			$configCheck = $this->configCheck($post, true);
			if ($configCheck["code"] != $this->success) {
				return json($configCheck);
			}
			$db = \think\Db::connect(["type" => "mysql", "hostname" => $post["mysql_hostname"], "database" => $post["mysql_database"], "username" => $post["mysql_username"], "password" => $post["mysql_password"], "hostport" => $post["mysql_hostport"], "charset" => "utf8", "prefix" => $this->mysql_prefix]);
			$time = time();
			$admin_qq = $post["admin_qq"] ?? "";
			try {
				$install_sql = file_get_contents(\think\facade\Env::get("root_path") . "system/install/install.sql");
				$install_sql = explode(";\r\n", trim($install_sql));
				foreach ($install_sql as $sql) {
					if (empty($sql)) {
						continue;
					}
					$db->query($sql);
				}
				$root_path = \think\facade\Env::get("root_path");
				$system_version_config = (include $root_path . "system/config/version.php");
				if (!$db->name("system_config")->where(["type" => "system_auth", "name" => "product_key"])->value("value")) {
					$db->query("INSERT INTO `{$this->mysql_prefix}system_config` (`type` , `name` , `value`) VALUES ('system_auth' , 'product_key' , '{$post["system_product_key"]}')");
					$db->query("INSERT INTO `{$this->mysql_prefix}system_config` (`type` , `name` , `value`) VALUES ('system_auth' , 'mysql_version_id' , '{$system_version_config["version_id"]}')");
				} else {
					$db->query("UPDATE `{$this->mysql_prefix}system_config` SET `value` = '{$post["system_product_key"]}' WHERE `type`='system_auth' AND `name`='product_key'");
				}
				$db->query("INSERT INTO `{$this->mysql_prefix}system_config` (`type` , `name` , `value`) VALUES ('website' , 'title' , '爱码科技')");
				$db->query("INSERT INTO `{$this->mysql_prefix}system_config` (`type` , `name` , `value`) VALUES ('website' , 'logo' , 'https://aimakeji-static.oss-cn-hangzhou.aliyuncs.com/logo/square-black-transparent_284_284.png')");
				$db->query("INSERT INTO `{$this->mysql_prefix}system_config` (`type` , `name` , `value`) VALUES ('website' , 'keywords' , '')");
				$db->query("INSERT INTO `{$this->mysql_prefix}system_config` (`type` , `name` , `value`) VALUES ('website' , 'description' , '')");
				$db->query("INSERT INTO `{$this->mysql_prefix}system_config` (`type` , `name` , `value`) VALUES ('website' , 'favicon' , 'https://aimakeji-static.oss-cn-hangzhou.aliyuncs.com/logo/square-black-transparent_284_284.png')");
				$db->query("INSERT INTO `{$this->mysql_prefix}system_config` (`type` , `name` , `value`) VALUES ('website' , 'bottom_copyright' , '产品官网：shuanq.cn')");
				$db->query("INSERT INTO `{$this->mysql_prefix}system_config` (`type` , `name` , `value`) VALUES ('website' , 'filing_number' , '')");
				$db->query("INSERT INTO `{$this->mysql_prefix}system_config` (`type` , `name` , `value`) VALUES ('website' , 'qq' , '{$admin_qq}')");
				$db->query("INSERT INTO `{$this->mysql_prefix}system_config` (`type` , `name` , `value`) VALUES ('map' , 'key' , '')");
				$admin_password = GeneratePassword($post["admin_password"]);
				$admin_token = md5(time());
				$db->query("INSERT INTO `{$this->mysql_prefix}system_admin` (`root` , `name` , `account` , `password` , `token` , `create_time`) VALUES (1 , '系统管理员' , '{$post["admin_account"]}' , '{$admin_password}' , '{$admin_token}' , {$time})");
			} catch (\Exception $e) {
				return json(["code" => $this->error, "msg" => "数据库安装出错，" . $e->getMessage()]);
			}
			file_put_contents("../system/install/install.lock", "");
			return json(["code" => $this->success, "msg" => "安装成功"]);
		} else {
			return json(["code" => $this->error, "msg" => "缺少参数"]);
		}
	}
	public function EnvCheck()
	{
		$data = [["name" => "PHP7.2", "support" => version_compare(PHP_VERSION, "7.2.0", ">"), "must" => true, "desc" => "PHP版本支持需 >= 7.2，建议用7.2"], ["name" => "Curl", "support" => $this->isExistsExpand("curl"), "must" => true, "desc" => "Curl扩展"], ["name" => "SG11", "support" => $this->isExistsExpand("SourceGuardian"), "must" => true, "desc" => "SG11加密扩展，全名为SourceGuardian"], ["name" => "openssl", "support" => $this->isExistsExpand("openssl"), "must" => true, "desc" => "openssl扩展"], ["name" => "json", "support" => $this->isExistsExpand("json"), "must" => true, "desc" => "json扩展"], ["name" => "session", "support" => $this->isExistsExpand("session"), "must" => true, "desc" => "session扩展"], ["name" => "PDO", "support" => $this->isExistsExpand("PDO"), "must" => true, "desc" => "PDO扩展"], ["name" => "pdo_mysql", "support" => $this->isExistsExpand("pdo_mysql"), "must" => true, "desc" => "pdo_mysql扩展"], ["name" => "xml", "support" => $this->isExistsExpand("xml"), "must" => true, "desc" => "xml扩展"], ["name" => "SimpleXML", "support" => $this->isExistsExpand("SimpleXML"), "must" => true, "desc" => "SimpleXML扩展"], ["name" => "zip", "support" => $this->isExistsExpand("zip"), "must" => true, "desc" => "zip扩展"], ["name" => "zlib", "support" => $this->isExistsExpand("zlib"), "must" => true, "desc" => "zlib扩展"], ["name" => "hash", "support" => $this->isExistsExpand("hash"), "must" => true, "desc" => "hash扩展"], ["name" => "gd", "support" => $this->isExistsExpand("gd"), "must" => true, "desc" => "gd扩展"], ["name" => "libxml", "support" => $this->isExistsExpand("libxml"), "must" => true, "desc" => "libxml扩展"], ["name" => "date", "support" => $this->isExistsExpand("date"), "must" => true, "desc" => "date扩展"], ["name" => "ZipArchive", "support" => $this->isExistsClass("ZipArchive"), "must" => true, "desc" => "ZipArchive类"]];
		return json(["code" => $this->success, "msg" => "检测成功", "data" => $data]);
	}
	public function configCheck($post, $databaseWriteConfig = true)
	{
		$databaseCheck = $this->databaseCheck($post, $databaseWriteConfig);
		if ($databaseCheck["code"] != $this->success) {
			return $databaseCheck;
		}
		return ["code" => $this->success, "msg" => "检测完成"];
	}
	private function databaseCheck($post, $write = true)
	{
		try {
			$db = \think\Db::connect(["type" => "mysql", "hostname" => $post["mysql_hostname"], "database" => $post["mysql_database"], "username" => $post["mysql_username"], "password" => $post["mysql_password"], "hostport" => $post["mysql_hostport"], "charset" => "utf8", "prefix" => $this->mysql_prefix]);
			if ($db->execute("select 1") == 1) {
				$tables = $db->query("show tables");
				if (count($tables) >= 1) {
					foreach ($tables as $table) {
						$tableName = array_values($table)[0];
						if (strpos($tableName, $this->mysql_prefix) !== false) {
							return ["code" => $this->error, "msg" => "查询到数据库内存在同名前缀的表,请检查是否已经安装或数据库安装过本公司其他的产品"];
						}
					}
					return ["code" => $this->error, "msg" => "请确保您的数据库是新建的空数据库(表数量不能超过1个)"];
				}
				if ($write) {
					file_put_contents("../config/database.php", $this->get_database_config_string($post["mysql_hostname"], $post["mysql_database"], $post["mysql_username"], $post["mysql_password"], $post["mysql_hostport"], $this->mysql_prefix));
				}
				return ["code" => $this->success, "msg" => "数据库检查成功"];
			} else {
				return ["code" => $this->error, "msg" => "数据库连接失败，请检查参数是否正确"];
			}
		} catch (\Exception $e) {
			return ["code" => $this->error, "msg" => "数据库连接失败，" . $e->getMessage()];
		}
	}
	private function get_database_config_string($hostname, $database, $username, $password, $hostport, $prefix = "aimakeji_")
	{
		$data = "<?php
return [
    // 数据库类型
    'type'            => 'mysql',
    // 服务器地址
    'hostname'        => '{$hostname}',
    // 数据库名
    'database'        => '{$database}',
    // 用户名
    'username'        => '{$username}',
    // 密码
    'password'        => '{$password}',
    // 端口
    'hostport'        => '{$hostport}',
    // 连接dsn
    'dsn'             => '',
    // 数据库连接参数
    'params'          => [],
    // 数据库编码默认采用utf8
    'charset'         => 'utf8mb4',
    // 数据库表前缀
    'prefix'          => '{$prefix}',
    // 数据库调试模式
    'debug'           => true,
    // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
    'deploy'          => 0,
    // 数据库读写是否分离 主从式有效
    'rw_separate'     => false,
    // 读写分离后 主服务器数量
    'master_num'      => 1,
    // 指定从服务器序号
    'slave_no'        => '',
    // 自动读取主库数据
    'read_master'     => false,
    // 是否严格检查字段是否存在
    'fields_strict'   => true,
    // 数据集返回类型
    'resultset_type'  => 'array',
    // 自动写入时间戳字段
    'auto_timestamp'  => false,
    // 时间字段取出后的默认时间格式
    'datetime_format' => 'Y-m-d H:i:s',
    // 是否需要进行SQL性能分析
    'sql_explain'     => false,
    // Builder类
    'builder'         => '',
    // Query类
    'query'           => '\\think\\db\\Query',
    // 是否需要断线重连
    'break_reconnect' => true,
    // 断线标识字符串
    'break_match_str' => [],
];
";
		return $data;
	}
	private function isExistsExpand($Name)
	{
		$list = get_loaded_extensions();
		return in_array($Name, $list);
	}
	private function isExistsFunction($Name)
	{
		if (function_exists($Name)) {
			return true;
		} else {
			return false;
		}
	}
	private function isExistsClass($Name)
	{
		if (class_exists($Name)) {
			return true;
		} else {
			return false;
		}
	}
}